package com.linkin.homepage.view;


import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.appbar.AppBarLayout;

public class FixedCoordinatorLayout extends CoordinatorLayout {

    private AppBarLayout mAppBarLayout;
    private RecyclerView mRecyclerView;
    private OnDrawListener mDrawListener = null;
    private boolean mIsBeingDragged = false;

    // scrollbar
    private float mRatio = 1.0f;
    private int mRecyclerViewOffset = 0;
    private int mRecyclerViewRange = 0;
    private float mAvgItemHeight = 0;

    public interface OnDrawListener {
        void onDraw();
    }

    public FixedCoordinatorLayout(Context context) {
        super(context);
        init();
    }

    public FixedCoordinatorLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public FixedCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setWillNotDraw(false);
    }

    public void setOnDrawListener(OnDrawListener drawListener) {
        setWillNotDraw(false);
        mDrawListener = drawListener;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View v = getChildAt(i);
            if (v instanceof AppBarLayout) {
                mAppBarLayout = (AppBarLayout) v;
                continue;
            }

            if (v instanceof RecyclerView) {
                mRecyclerView = (RecyclerView) v;
            }
        }
    }

    @Override
    protected int computeVerticalScrollRange() {
        compute();
        int range = 0;
        if (mAppBarLayout != null && mAppBarLayout.getVisibility() != GONE) {
            range += Math.round(mAppBarLayout.getTotalScrollRange() * mRatio);
        }
        range += mRecyclerViewRange;
        return range;
    }

    @Override
    protected int computeVerticalScrollOffset() {
        compute();
        int offset = 0;
        if (mAppBarLayout != null && mAppBarLayout.getVisibility() != GONE) {
            CoordinatorLayout.Behavior behavior =
                    ((CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams()).getBehavior();
            if (behavior instanceof AppBarLayout.Behavior) {
                AppBarLayout.Behavior appBarLayoutBehavior = (AppBarLayout.Behavior) behavior;
                offset += Math.round(-appBarLayoutBehavior.getTopAndBottomOffset() * mRatio);
            }
        }
        offset += mRecyclerViewOffset;
        return offset;
    }

    private void compute() {
        if (mRecyclerView != null && mRecyclerView.getVisibility() != GONE) {
            mRecyclerViewOffset = mRecyclerView.computeVerticalScrollOffset();
            mRecyclerViewRange = mRecyclerView.computeVerticalScrollRange();

            RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
            if (adapter != null && adapter.getItemCount() > 0) {
                if (mRecyclerViewOffset == 0) {
                    mAvgItemHeight = (float) mRecyclerViewRange / adapter.getItemCount();
                    mRatio = 1;
                } else {
                    if (mAvgItemHeight > 0) {
                        float avgItemHeight = (float) mRecyclerViewRange / adapter.getItemCount();
                        mRatio = avgItemHeight / mAvgItemHeight;
                    } else {
                        mRatio = 1;
                    }
                }
            } else {
                mRatio = 1;
            }
        } else {
            mRecyclerViewOffset = 0;
            mRecyclerViewRange = 0;
            mRatio = 1;
        }
    }

    @Override
    public void draw(Canvas canvas)  {
        super.draw(canvas);
        if (mDrawListener != null) {
            mDrawListener.onDraw();
        }
    }

    @Override
    public boolean awakenScrollBars() {
        return super.awakenScrollBars();
    }

    public boolean isBeingDragged() {
        return mIsBeingDragged;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction() & MotionEvent.ACTION_MASK;
        if (action == MotionEvent.ACTION_DOWN) {
            mIsBeingDragged = true;
        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            mIsBeingDragged = false;
        }
        return super.dispatchTouchEvent(ev);
    }

    public void scrollToTop() {
        scrollToOffset(0);
    }

    public void scrollToRecyclerView() {
        if (mAppBarLayout != null && mAppBarLayout.getTotalScrollRange() > 0
                && mRecyclerView != null && mRecyclerView.getHeight() > 0) {
            int offset = mAppBarLayout.getTotalScrollRange() - (getHeight() - mRecyclerView.getHeight());
            if (offset < 0) {
                offset = 0;
            }
            scrollToOffset(offset);
            mRecyclerView.scrollToPosition(0);
        }
    }

    public boolean isScrollToRecyclerView() {
        if (mAppBarLayout != null && mAppBarLayout.getTotalScrollRange() > 0
                && mRecyclerView != null && mRecyclerView.getHeight() > 0) {
            int offset = mAppBarLayout.getTotalScrollRange() - (getHeight() - mRecyclerView.getHeight());
            return offset == calcVerticalScrollOffset();
        }
        return false;
    }

    private void scrollToOffset(int offset) {
        if (mRecyclerView != null) {
            mRecyclerView.stopScroll();
        }

        if (mAppBarLayout != null) {
            CoordinatorLayout.Behavior behavior =
                    ((CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams()).getBehavior();
            if (behavior instanceof AppBarLayout.Behavior) {
                AppBarLayout.Behavior appBarLayoutBehavior = (AppBarLayout.Behavior) behavior;
                int topAndBottomOffset = appBarLayoutBehavior.getTopAndBottomOffset();
                if (topAndBottomOffset != -offset) {
                    appBarLayoutBehavior.setTopAndBottomOffset(-offset);
                }
            }
        }
    }

    private int calcVerticalScrollOffset() {
        int offset = 0;
        if (mAppBarLayout != null && mAppBarLayout.getVisibility() != GONE) {
            CoordinatorLayout.Behavior behavior =
                    ((CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams()).getBehavior();
            if (behavior instanceof AppBarLayout.Behavior) {
                AppBarLayout.Behavior appBarLayoutBehavior = (AppBarLayout.Behavior) behavior;
                offset = -appBarLayoutBehavior.getTopAndBottomOffset();
            }
        }

        if (mRecyclerView != null && mRecyclerView.getVisibility() != GONE) {
            offset += mRecyclerView.computeVerticalScrollOffset();
        }
        return offset;
    }
}
